﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Caching;
using System.Text;
using System.Threading.Tasks;
using log4net.Appender;

namespace CM.Resources.Web.Comm.Log
{
    /// <summary>
    /// Log4Net文件写入器的重写
    /// </summary>
    public class Log4NetFileAppender : FileAppender
    {
        static MemoryCache memoryCache = new MemoryCache("Log4NetFileAppender");

        protected override void Append(log4net.Core.LoggingEvent loggingEvent)
        {
            doSubLog(loggingEvent);
            //base.Append(loggingEvent);
        }

        private FileAppender GetFileAppender(string key, Func<string, FileAppender> callFun)
        {
            var obj = memoryCache.Get(key);
            if (obj != null)
            {
                var fileAppender = obj as FileAppender;
                if (fileAppender != null)
                {
                    return fileAppender;
                }
            }
            var appender = callFun(key);
            memoryCache.Set(key, appender, new DateTimeOffset(DateTime.Now.AddDays(1)));
            return appender;
        }
        /// <summary>
        /// 写文件日志
        /// </summary>
        /// <param name="loggingEvent"></param>
        private void doSubLog(log4net.Core.LoggingEvent loggingEvent)
        {
            string date = DateTime.Now.ToString("yyyy-MM-dd");
            string subLogName = String.Format("{0}_{1}", date, loggingEvent.LoggerName);
            var fileAppender = GetFileAppender(subLogName, (string key) => InitFileAppender(loggingEvent.LoggerName, date)); 
            fileAppender.DoAppend(loggingEvent);
            if (loggingEvent.Level == log4net.Core.Level.Error)
            {
                subLogName = String.Format("{0}_{1}", date, "Global_Error_Log");
                fileAppender = GetFileAppender(subLogName, (string key) => InitFileAppender("Global_Error_Log", date));
                fileAppender.DoAppend(loggingEvent);
            } 
        }

        private FileAppender InitFileAppender(string logName, string fileName)
        {
            var fileAppender = new FileAppender();
            fileAppender.File = Path.Combine(Path.GetDirectoryName(File), logName, fileName + ".txt");
            fileAppender.Layout = Layout;
            fileAppender.AppendToFile = true;
            fileAppender.Threshold = Threshold;
            fileAppender.Encoding = Encoding.UTF8;
            fileAppender.ActivateOptions();
            return fileAppender;
        }

        protected override void Append(log4net.Core.LoggingEvent[] loggingEvents)
        {
            foreach (var loggingEvent in loggingEvents)
            {
                doSubLog(loggingEvent);
            }
            //base.Append(loggingEvents);
        }


    }
}
